package pa3;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Observable;
import java.util.Timer;

public class HostState extends Observable {
	
	private int failureProbability = 0;
	private String name;
	private HashMap<String, Host> otherHosts;
	private HashMap<String, Timer> checkTimers;
	private boolean isCrashed = false;
	private HashMap<String,Timer> checkScheduleTimers;
	private StringBuilder log;
	
	public HostState(String hostName, int failureProbability){
		this.name = hostName;
		this.failureProbability = failureProbability;
		this.checkTimers = new HashMap<String, Timer>();
		this.log = new StringBuilder();
	}

	public int getFailureProbability() {
		return failureProbability;
	}

	public void setFailureProbability(int failureProbability) {
		this.failureProbability = failureProbability;
		setChanged();
		notifyObservers(failureProbability);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public HashMap<String, Host> getOtherHosts() {
		if(otherHosts == null)
			otherHosts = new HashMap<String, Host>();
		return otherHosts;
	}

	public void setOtherHosts(HashMap<String, Host> otherHosts) {
		this.otherHosts = otherHosts;
		setChanged();
		notifyObservers(otherHosts);
	}

	public HashMap<String, Timer> getCheckTimers() {
		if(checkTimers == null)
			checkTimers = new HashMap<String, Timer>();
		return checkTimers;
	}

	public void setCheckTimers(HashMap<String, Timer> checkTimers) {
		this.checkTimers = checkTimers;
		setChanged();
		notifyObservers(checkTimers);
	}

	public HashMap<String,Timer> getCheckScheduleTimers() {
		return checkScheduleTimers;
	}

	public void setCheckScheduleTimers(HashMap<String,Timer> checkScheduleTimer) {
		this.checkScheduleTimers = checkScheduleTimer;
		setChanged();
		notifyObservers(checkScheduleTimer);
	}

	public void resetOtherHosts() {
		otherHosts = null;
	}

	public void cancelCheckTimers() {
		if(checkTimers != null){
			Iterator<String> iter = checkTimers.keySet().iterator();
			while(iter.hasNext()){
				String hostName = iter.next();
				checkTimers.get(hostName).cancel();
			}

		}		
	}

	public void resetCheckTimers() {
		checkTimers = null;
	}

	public void cancelCheckScheduleTimers() {
		if(checkScheduleTimers != null){
			Iterator<String> iter = checkScheduleTimers.keySet().iterator();
			while(iter.hasNext()){
				String hostName = iter.next();
				checkScheduleTimers.get(hostName).cancel();
			}

		}	
		setChanged();
		notifyObservers(checkScheduleTimers);
	}

	public void resetCheckScheduleTimers() {
		checkScheduleTimers = null;
	}

	public void setCrashed(boolean isCrashed) {
		this.isCrashed = isCrashed;
		setChanged();
		notifyObservers(isCrashed);
	}

	public boolean isCrashed() {
		return isCrashed;
	}
	
	public synchronized void log(String msg){
		log.append(msg);
		setChanged();
		notifyObservers(log);
	}

	public void cancelTimerFor(String hostName) {
		Timer t = checkTimers.get(hostName);
		if(t != null)
			t.cancel();
		setChanged();
		notifyObservers(checkTimers);
	}

	public void addCheckTimerForHost(String hostName, Timer t) {
		checkTimers.put(hostName, t);
		setChanged();
		notifyObservers(checkTimers);
	}

	public void removeTimerForHost(String hostName) {
		checkTimers.remove(hostName);
		setChanged();
		notifyObservers(checkTimers);
	}
	
	public void cancelScheduleTimerFor(String hostName) {
		Timer t = checkScheduleTimers.get(hostName);
		if(t != null)
			t.cancel();
		setChanged();
		notifyObservers(checkScheduleTimers);
	}

	public void addCheckScheduleTimerForHost(String hostName, Timer t) {
		checkScheduleTimers.put(hostName, t);
		setChanged();
		notifyObservers(checkScheduleTimers);
	}

	public void removeScheduleTimerForHost(String hostName) {
		checkScheduleTimers.remove(hostName);
		setChanged();
		notifyObservers(checkScheduleTimers);
	}

	public String getLogString() {
		return log.toString();
	}
}
